package com.hs.wa.redis;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

public class JavaMailWithAttachments {
    public static void main(String[] args) throws Exception {

        //1.设置创建session需要的属性
        Properties props=new Properties();
        //设置邮件的传输协议，常用的协议有SMTP、POP3、IMAP4。这里我们使用qq邮箱发送
        //电子百邮件读取协议度(POP3和IMAP)、简单邮件传输协议（SMTP).我们选择stmp协议
        props.setProperty("mail.transport.protocol", "smtp");
        //设置发件人的邮箱的stmp服务地址(qq邮箱的服务地址)
        props.setProperty("mail.smtp.host", "smtp.qq.com");
        //开启请求认证
        props.setProperty("mail.smtp.auth", "true");

        // PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启),
        //     如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误,
        //     就需要开启 SSL 安全连接。
        /*
         			SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,
                     需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,
                         QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
         */

        //设置安全认证需要提供一个socketfactory，这个类由java提供
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //设置ssl安全认证的端口
        props.setProperty("mail.smtp.port", "465");
        //只处理ssl的链接，对于非ssl的链接不做处理
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        //设置socketfactory的端口，和ssl安全认证的端口一样就好了
        props.setProperty("mail.smtp.socketFactory.port", "465");

        //2.根据配置创建会话对象，用于和邮件服务交互,构造器被私有化，用其他方法创建对象
        Session session=Session.getInstance(props);
        //设置为debug模式，可以查看详细的发送log
        session.setDebug(true);

        //3.创建一封邮件，调用自己写的生成邮件的方法
        MimeMessage message=creatMimeMessage(session,"1332854729@qq.com","394407209@qq.com");

        //4.根据session创建传输对象
        Transport transport=session.getTransport();

        // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
        transport.connect("1332854729@qq.com","iwzjhignbphyidjb");

        //6.发送邮件，发到所有的收件地址，message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
        transport.sendMessage(message, message.getAllRecipients());
        //7.关闭连接
        transport.close();

    }



    /**
     * 创建一封复杂邮件（文本+图片+附件）
     */

    //邮件的类型为mime
    public static MimeMessage creatMimeMessage(Session session,String sendMail, String receiveMail) throws Exception{
        //1.创建一封邮件,需要传一个session对象
        MimeMessage message=new MimeMessage(session);

        //2.from：发件人（昵称有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改昵称）
        //参数需要传一个address对象，address是接口，用他的实现类
        //三个参数：发件人账号，发件人名字，字符编码
        message.setFrom(new InternetAddress(sendMail, "发件人名字", "UTF-8"));

        //3.设置收件人，有三个类型，TO：普通收件人，CC：抄送人，BCC：密送人
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "普通收件人", "UTF-8"));
        //message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(receiveMail, "普通收件人", "UTF-8"));
        //message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(receiveMail, "普通收件人", "UTF-8"));

        //4.Subject：邮件主题（标题有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改标题）
        message.setSubject("这是标题","UTF-8");

        //5.创建一个图片节点
        MimeBodyPart imagePart=new MimeBodyPart();
        //创建数据控制对象读取本地文件,参数为DataSource
        DataHandler imageDataHander=new DataHandler(new FileDataSource("D:\\springnew\\cloud\\koot\\src\\main\\resources\\2.jpg"));
        //将图片数据添加到图片节点
        imagePart.setDataHandler(imageDataHander);
        //为节点设置唯一编号，在文本节点中引用该ID
        imagePart.setContentID("image");

        //6.创建文本节点，为了加载图片节点(图片是通过文本的形式放在网页中的，跟html一样)
        MimeBodyPart  textPart=new MimeBodyPart();
        //这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
        textPart.setContent("这是一张图片<br/><img src='cid:image'/>", "text/html;charset=UTF-8");

        //7.创建复合节点(将图片节点和文本节点合成一个符合节点)
        MimeMultipart mm_text_image=new MimeMultipart();
        mm_text_image.addBodyPart(textPart);
        mm_text_image.addBodyPart(imagePart);
        //设置文本和图片的关系，关联关系
        mm_text_image.setSubType("related");

        //8.将文本节点+图片节点合成的复合节点转化为普通节点(因为正文中只能出现普通节点，不能出现复合节点)
        MimeBodyPart text_image=new MimeBodyPart();
        text_image.setContent(mm_text_image);

        //9.创建附件节点
        MimeBodyPart attachment = new MimeBodyPart();
        //数据控制对象
        DataHandler attDataHandler=new DataHandler(new FileDataSource("D:\\springnew\\cloud\\koot\\src\\main\\resources\\6.jpg"));
        attachment.setDataHandler(attDataHandler);
        //设置附件名字(用原来附件的名字就好)用MimeUtilty工具类防止乱码
        attachment.setFileName(MimeUtility.encodeText(attDataHandler.getName()));

        //10。将附件节点和刚才的普通节点(文本节点+图片节点合成的复合节点转化为普通节点)转化成复合节点
        MimeMultipart mm=new MimeMultipart();
        mm.addBodyPart(text_image);
        mm.addBodyPart(attachment);// 如果有多个附件，可以创建多个多次添加
        //设置二者的关系，混合关系
        mm.setSubType("mixed");

        //11.将整个复合节点作为邮件的正文
        //这里区分一下，如果将邮件的东西(图片)放到正文里面那只能是bodypart，现在这个已经不是纯正文了，还带有附件，所以可以使用复合节点
        message.setContent(mm);
//			//5.Content：邮件正文（可以使用html标签）（内容有广告嫌疑，避免被邮件服务器误认为是滥发广告以至返回失败，请修改发送内容）
//			message.setContent("z这是正文.....","text/html;charset=utf-8");

        //6.设置发件时间
        message.setSentDate(new Date());

        //7.保存设置
        message.saveChanges();
        return message;
    }

}
